home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a15 / Base / AbstractData.cp next >
Encoding:
Text File  |  1996-02-19  |  16.8 KB  |  449 lines  |  [TEXT/CWIE]

  1.  
  2. #include "AbstractData.h"
  3.  
  4. //
  5. // For BlockMoveData
  6. //
  7. #include <Memory.h>
  8.  
  9. //--------------------------------------------------------------------------------
  10. // CopyMemory
  11. // 
  12. // The idea of having our own wrapper for memory copying is that memcpy is
  13. // not always available (it should be, but it doesn't appear in some minimal
  14. // configurations of CodeWarrior, for example)
  15. //--------------------------------------------------------------------------------
  16. void CopyMemory(const void *srcPtr, void *destPtr, SInt32 byteCount)
  17. {
  18.     BlockMoveData(srcPtr, destPtr, byteCount); // memcpy(destPtr, srcPtr, byteCount);
  19. }
  20.  
  21.  
  22. //
  23. // Global list of compare behaviors
  24. //
  25. TAbstractCompareBehavior* TAbstractDataReference::fFirstBehavior = nil;
  26.  
  27. //================================================================================
  28. // Class TAbstractCompareBehavior
  29. //================================================================================
  30.  
  31. //--------------------------------------------------------------------------------
  32. // TAbstractCompareBehavior::TAbstractCompareBehavior
  33. //--------------------------------------------------------------------------------
  34. TAbstractCompareBehavior::TAbstractCompareBehavior()
  35. {
  36.     fNextBehavior = nil;
  37. }
  38.     
  39. //--------------------------------------------------------------------------------
  40. // TAbstractCompareBehavior::CompareDynamicBehavior
  41. //
  42. // Compare behaviors should look for data types they can compare
  43. //--------------------------------------------------------------------------------
  44. CompareEnumeration TAbstractCompareBehavior::CompareDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const
  45. {
  46.     if(fNextBehavior)
  47.         return fNextBehavior->CompareDynamicBehavior(object1, object2);
  48.     else
  49.         return TAbstractDataReference::CompareDefaultBehavior(object1, object2);
  50. }
  51.  
  52. //--------------------------------------------------------------------------------
  53. // TAbstractCompareBehavior::ContainsDynamicBehavior
  54. //--------------------------------------------------------------------------------
  55. Boolean TAbstractCompareBehavior::ContainsDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const
  56. {
  57.     if(fNextBehavior)
  58.         return fNextBehavior->ContainsDynamicBehavior(object1, object2);
  59.     else
  60.         return TAbstractDataReference::ContainsDefaultBehavior(object1, object2);
  61. }
  62.  
  63. //================================================================================
  64. // Class TAbstractDataReference
  65. //================================================================================
  66.  
  67. //----------------------------------------------------------------------------------------
  68. // TAbstractDataReference::TAbstractDataReference
  69. //----------------------------------------------------------------------------------------
  70. TAbstractDataReference::TAbstractDataReference()
  71. {
  72. }
  73.  
  74. //----------------------------------------------------------------------------------------
  75. // TAbstractDataReference::~TAbstractDataReference
  76. //----------------------------------------------------------------------------------------
  77. TAbstractDataReference::~TAbstractDataReference()
  78. {
  79. }
  80.  
  81. //----------------------------------------------------------------------------------------
  82. // TAbstractDataReference::DirectlyReadable: 
  83. //----------------------------------------------------------------------------------------
  84. Boolean TAbstractDataReference::DirectlyReadable() const
  85. {
  86.     return false;
  87. } // TAbstractDataReference::DirectlyReadable 
  88.     
  89. //----------------------------------------------------------------------------------------
  90. // TAbstractDataReference::Writable: 
  91. //----------------------------------------------------------------------------------------
  92. Boolean TAbstractDataReference::Writable() const
  93. {
  94.     return false;
  95. } // TAbstractDataReference::Writable 
  96.     
  97. //----------------------------------------------------------------------------------------
  98. // TAbstractDataReference::DirectlyWritable: 
  99. //----------------------------------------------------------------------------------------
  100. Boolean TAbstractDataReference::DirectlyWritable() const
  101. {
  102.     return false;
  103. } // TAbstractDataReference::DirectlyWritable 
  104.     
  105. //----------------------------------------------------------------------------------------
  106. // TAbstractDataReference::Resizable: 
  107. //----------------------------------------------------------------------------------------
  108. Boolean TAbstractDataReference::Resizable() const
  109. {
  110.     return false;
  111. } // TAbstractDataReference::Resizable 
  112.  
  113. //----------------------------------------------------------------------------------------
  114. // TAbstractDataReference::MaxLength: 
  115. //----------------------------------------------------------------------------------------
  116. SInt32 TAbstractDataReference::MaxLength() const
  117. {
  118.     return this->DataLength();
  119. } // TAbstractDataReference::MaxLength 
  120.  
  121. //----------------------------------------------------------------------------------------
  122. // TAbstractDataReference::CopyTo: 
  123. //----------------------------------------------------------------------------------------
  124. SInt32 TAbstractDataReference::CopyTo(char*, SInt32) const
  125. {
  126.     return 0;
  127. } // TAbstractDataReference::CopyTo 
  128.  
  129. //----------------------------------------------------------------------------------------
  130. // TAbstractDataReference::SetDataType: 
  131. //----------------------------------------------------------------------------------------
  132. Boolean TAbstractDataReference::SetDataType(SInt32)
  133. {
  134.     return false;
  135. } // TAbstractDataReference::SetDataType 
  136.  
  137. //----------------------------------------------------------------------------------------
  138. // TAbstractDataReference::SetDataLength: 
  139. //----------------------------------------------------------------------------------------
  140. SInt32 TAbstractDataReference::SetDataLength(SInt32)
  141. {
  142.     return this->DataLength();
  143. } // TAbstractDataReference::SetDataLength 
  144.  
  145. //----------------------------------------------------------------------------------------
  146. // TAbstractDataReference::CopyFrom: 
  147. //----------------------------------------------------------------------------------------
  148. Boolean TAbstractDataReference::CopyFrom(const TAbstractDataReference&, Boolean)
  149. {
  150.     return false;
  151. } // TAbstractDataReference::CopyFrom 
  152.     
  153. //----------------------------------------------------------------------------------------
  154. // TAbstractDataReference::Resize: 
  155. //----------------------------------------------------------------------------------------
  156. Boolean TAbstractDataReference::Resize(SInt32)
  157. {
  158.     return false;
  159. } // TAbstractDataReference::Resize 
  160.     
  161. //----------------------------------------------------------------------------------------
  162. // TAbstractDataReference::Data: 
  163. //----------------------------------------------------------------------------------------
  164. const char* TAbstractDataReference::Data() const
  165. {
  166.     return nil;
  167. } // TAbstractDataReference::Data 
  168.  
  169. //----------------------------------------------------------------------------------------
  170. // TAbstractDataReference::Data: 
  171. //----------------------------------------------------------------------------------------
  172. char* TAbstractDataReference::Data()
  173. {
  174.     return nil;
  175. } // TAbstractDataReference::Data 
  176.  
  177. //--------------------------------------------------------------------------------
  178. // TAbstractDataReference::Compare
  179. //--------------------------------------------------------------------------------
  180. CompareEnumeration TAbstractDataReference::Compare(const TAbstractDataReference& object2) const
  181. {
  182.     //
  183.     // ◊if we're given references that we can't read directly,
  184.     // then we should copy the data somewhere else and compare
  185.     // against that.
  186.     //
  187.     if(this->DirectlyReadable() && object2.DirectlyReadable())
  188.         return TAbstractDataReference::Compare(*this, object2);
  189.     else
  190.         return kCantCompare;
  191. }
  192.  
  193. //--------------------------------------------------------------------------------
  194. // TAbstractDataReference::Contains
  195. //--------------------------------------------------------------------------------
  196. Boolean TAbstractDataReference::Contains(const TAbstractDataReference& object2) const
  197. {
  198.     if((this->DirectlyReadable() == false) || (object2.DirectlyReadable() == false))
  199.         return false;
  200.     else if(fFirstBehavior)
  201.         return fFirstBehavior->ContainsDynamicBehavior(*this, object2);
  202.     else
  203.         return TAbstractDataReference::ContainsDefaultBehavior(*this, object2);
  204. }
  205.  
  206. //--------------------------------------------------------------------------------
  207. // TAbstractDataReference::AddCompareBehavoir
  208. //--------------------------------------------------------------------------------
  209. void TAbstractDataReference::AddCompareBehavoir(TAbstractCompareBehavior* behavior)
  210. {
  211.     if(fFirstBehavior != nil)
  212.         behavior->SetNextBehavior(fFirstBehavior);
  213.     
  214.     fFirstBehavior = behavior;
  215. } // TAbstractDataReference::AddCompareBehavoir
  216.  
  217. //--------------------------------------------------------------------------------
  218. // TAbstractDataReference::Compare
  219. //--------------------------------------------------------------------------------
  220. CompareEnumeration TAbstractDataReference::Compare(const TAbstractDataReference& object1, const TAbstractDataReference& object2)
  221. {
  222.     if(fFirstBehavior)
  223.         return fFirstBehavior->CompareDynamicBehavior(object1, object2);
  224.     else
  225.         return TAbstractDataReference::CompareDefaultBehavior(object1, object2);
  226. }
  227.  
  228. //--------------------------------------------------------------------------------
  229. // TAbstractDataReference::CompareDefaultBehavior
  230. //
  231. // If none of the compare behaviors know how to do the data comparison, then
  232. // assume a simple byte-stream compare is good enough (works for C Strings)
  233. //--------------------------------------------------------------------------------
  234. CompareEnumeration TAbstractDataReference::CompareDefaultBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2)
  235. {
  236.     const char* object1Data = object1.Data();
  237.     const char* object2Data = object2.Data();
  238.     SInt32 object1Length = object1.DataLength();
  239.     SInt32 object2Length = object2.DataLength();
  240.     SInt32 bytesToCompare = object1Length > object2Length ? object2Length : object1Length;
  241.     
  242.     //
  243.     // Scan through the first N bytes; stop comparing
  244.     // as soon as an unequal section is found
  245.     //
  246.     while(bytesToCompare)
  247.         {
  248.         if(*object2Data < *object1Data)
  249.             return kSecondObjectComesBefore;
  250.         if(*object2Data > *object1Data)
  251.             return kSecondObjectComesAfter;
  252.         
  253.         ++object1Data;
  254.         ++object2Data;
  255.         --bytesToCompare;
  256.         }
  257.     
  258.     //
  259.     // If the first N bytes of both data streams are
  260.     // the same, then the shorter structure comes before.
  261.     //
  262.     if(object2Length < object1Length)
  263.         return kSecondObjectComesBefore;
  264.     if(object2Length > object1Length)
  265.         return kSecondObjectComesAfter;
  266.     
  267.     //
  268.     // Every byte is equal & the length is the same,
  269.     // so the two objects are equal
  270.     //
  271.     return kObjectKeysEqual;
  272. }
  273.  
  274. //--------------------------------------------------------------------------------
  275. // TAbstractDataReference::ContainsDefaultBehavior
  276. //--------------------------------------------------------------------------------
  277. Boolean TAbstractDataReference::ContainsDefaultBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2)
  278. {
  279.     SInt32 sizeDifference = object1.DataLength() - object2.DataLength();
  280.     const char* dataStart = object1.Data();
  281.     Boolean isContained = false;
  282.     
  283.     while(sizeDifference >= 0)
  284.     {
  285.         TConstDataReference containsTest(object1.DataType(), dataStart, object2.DataLength());
  286.         if(containsTest.Compare(object2) == kObjectKeysEqual)
  287.         {
  288.             isContained = true;
  289.             break;
  290.         }
  291.         ++dataStart;
  292.         --sizeDifference;
  293.     }
  294.     
  295.     return isContained; 
  296. } // TAbstractDataReference::ContainsDefaultBehavior
  297.  
  298. //================================================================================
  299. // Class TConstDataReference
  300. //================================================================================
  301.  
  302. //----------------------------------------------------------------------------------------
  303. // TConstDataReference::DirectlyReadable: 
  304. //----------------------------------------------------------------------------------------
  305. Boolean TConstDataReference::DirectlyReadable() const
  306. {
  307.     return true;
  308. } // TConstDataReference::DirectlyReadable 
  309.  
  310. //----------------------------------------------------------------------------------------
  311. // TConstDataReference::DataType: 
  312. //----------------------------------------------------------------------------------------
  313. SInt32 TConstDataReference::DataType() const
  314. {
  315.     return fDataType;
  316. } // TConstDataReference::DataType 
  317.  
  318. //----------------------------------------------------------------------------------------
  319. // TConstDataReference::DataLength: 
  320. //----------------------------------------------------------------------------------------
  321. SInt32 TConstDataReference::DataLength() const
  322. {
  323.     return fDataLength;
  324. } // TConstDataReference::DataLength 
  325.  
  326. //----------------------------------------------------------------------------------------
  327. // TConstDataReference::CopyTo: 
  328. //----------------------------------------------------------------------------------------
  329. SInt32 TConstDataReference::CopyTo(char* destination, SInt32 maxBytesToCopy) const
  330. {
  331.     SInt32 bytesToCopy = (fDataLength > maxBytesToCopy) ? maxBytesToCopy : fDataLength;
  332.     
  333.     CopyMemory(fData, destination, bytesToCopy);
  334.     
  335.     return bytesToCopy;
  336. } // TConstDataReference::CopyTo 
  337.     
  338. //----------------------------------------------------------------------------------------
  339. // TConstDataReference::Data: 
  340. //----------------------------------------------------------------------------------------
  341. const char* TConstDataReference::Data() const
  342. {
  343.     return fData;
  344. } // TConstDataReference::Data 
  345.  
  346. //================================================================================
  347. // Class TUpdataDataReference
  348. //================================================================================
  349.  
  350. //--------------------------------------------------------------------------------
  351. // TUpdataDataReference::Writable
  352. //--------------------------------------------------------------------------------
  353. Boolean TUpdataDataReference::Writable() const
  354. {
  355.     return true;
  356. }
  357.  
  358. //--------------------------------------------------------------------------------
  359. // TUpdataDataReference::DirectlyWritable
  360. //--------------------------------------------------------------------------------
  361. Boolean TUpdataDataReference::DirectlyWritable() const
  362. {
  363.     return true;
  364. }
  365.  
  366. //--------------------------------------------------------------------------------
  367. // TUpdataDataReference::MaxLength
  368. //--------------------------------------------------------------------------------
  369. SInt32 TUpdataDataReference::MaxLength() const
  370. {
  371.     return fMaxLength;
  372. }
  373.  
  374. //--------------------------------------------------------------------------------
  375. // TUpdataDataReference::SetDataType
  376. //--------------------------------------------------------------------------------
  377. Boolean TUpdataDataReference::SetDataType(SInt32 newType)
  378. {
  379.     fDataType = newType;
  380.     return true;
  381. }
  382.  
  383. //--------------------------------------------------------------------------------
  384. // TUpdataDataReference::SetDataLength
  385. //--------------------------------------------------------------------------------
  386. SInt32 TUpdataDataReference::SetDataLength(SInt32 newLength)
  387. {
  388.     fDataLength = newLength > fMaxLength ? fMaxLength : newLength;
  389.  
  390.     return fDataLength;
  391. }
  392.  
  393. //--------------------------------------------------------------------------------
  394. // TUpdataDataReference::CopyFrom
  395. //--------------------------------------------------------------------------------
  396. Boolean TUpdataDataReference::CopyFrom(const TAbstractDataReference& source, Boolean allowDataToClip)
  397. {
  398.     Boolean copyFits = source.DataLength() <= fMaxLength;
  399.     
  400.     if(copyFits || allowDataToClip)
  401.     {
  402.         fDataLength = source.CopyTo(this->Data(), fMaxLength);
  403.         this->SetDataType(source.DataType());
  404.     }
  405.     
  406.     return copyFits;
  407. } // TUpdataDataReference::CopyFrom
  408.  
  409. //--------------------------------------------------------------------------------
  410. // TUpdataDataReference::Data
  411. //--------------------------------------------------------------------------------
  412. char* TUpdataDataReference::Data()
  413. {
  414.     return (char*)fData;
  415. }
  416.  
  417. //================================================================================
  418. // Class TTransientDataReference
  419. //================================================================================
  420.  
  421. //--------------------------------------------------------------------------------
  422. // TTransientDataReference::TTransientDataReference
  423. //--------------------------------------------------------------------------------
  424. TTransientDataReference::TTransientDataReference(const TAbstractDataReference& data) :
  425.     TConstDataReference(data.DataType(), nil, data.DataLength()), fAllocatedData(false)
  426. {
  427.     if(data.DirectlyReadable() == false)
  428.     {
  429.         fData            = new char[data.DataLength()];
  430.         fAllocatedData    = true;
  431.         
  432.         data.CopyTo((char*)fData, fDataLength);
  433.     }
  434.     else
  435.     {
  436.         fData            = data.Data();
  437.     }
  438. }
  439.  
  440. //--------------------------------------------------------------------------------
  441. // TTransientDataReference::~TTransientDataReference
  442. //--------------------------------------------------------------------------------
  443. TTransientDataReference::~TTransientDataReference()
  444. {
  445.     if(fAllocatedData)
  446.         delete (char*)fData;
  447. }
  448.  
  449.